﻿/*文件注释
 * ===============================================================================
 * 说明：
 * 作者：曾永佑
 * 版本：V1.0
 * 创建日期：2013-02-10
 * 完成日期： 
 * 修改纪录：  
 * ===============================================================================
 */  
        
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using SRF.Data.Impl;

namespace SRF.Data
{
    /// <summary>
    /// 数据操作类
    /// </summary>
    public class DBHelper : DBHelperBase
    {
        DatabaseType dbtype;
        string connectionString;

        public DBHelper(DatabaseType dbtype, string connectionString)
        {
            this.dbtype = dbtype;
            this.connectionString = connectionString;
        }

        public override IQuery GetQuery(string sql, string mode = "")
        {
            var nameSql = Queries.SingleOrDefault(m => m.Name == sql.ToLower());
            if (nameSql != null)
            {
                sql = nameSql.Sql.Trim('\n', ' ');
                mode = string.IsNullOrEmpty(mode) ? nameSql.Mode : mode;
            }
            var query = new Query(sql, mode, Database); 

            return query;
        }

        /// <summary>
        /// 连接字符串
        /// </summary>
        public override string ConnectionString
        {
            get { return Database.ConnectionString; }
        }

        Database _database;
        public override Database Database
        {
            get
            { 
                if (_database == null)
                    _database = DatabaseFactory.Get(dbtype, connectionString);
                return _database;
            }
        }

        #region 实体映射

        public override T Get<T>(object id)
        {
            StringBuilder fieldBuilder = new StringBuilder();
            //解析
            var classMapping = ClassMappings.SingleOrDefault(m => typeof(T).AssemblyQualifiedName.Replace(" ", "").StartsWith(m.Name));
            foreach (var p in classMapping.Propertys.Where(m => m.Insert == true))
            {
                fieldBuilder.AppendFormat("{0}{2}{1} {0}{3}{1},", Database.OpenQuote, Database.CloseQuote, p.Column, p.Name);
            }
            var sql = string.Format("select {0} from {1} where {2}", fieldBuilder.ToString().TrimEnd(','), classMapping.Table, MakeWhere(id));

            return GetQuery(sql).SetParameter(id).UniqueResult<T>();
        }
        public override int Insert(object entity)
        {
            StringBuilder fieldBuilder = new StringBuilder();
            StringBuilder valueBuilder = new StringBuilder();
            //解析
            var classMapping = ClassMappings.SingleOrDefault(m => entity.GetType().AssemblyQualifiedName.Replace(" ", "").StartsWith(m.Name));
            foreach (var p in classMapping.Propertys.Where(m => m.Insert == true))
            {
                fieldBuilder.Append(Database.OpenQuote + p.Column + Database.CloseQuote + ",");
                valueBuilder.Append(Database.ParameterToken + p.Name + ",");
            }

            var sql = string.Format("insert into {0}({1})values({2})", classMapping.Table, fieldBuilder.ToString().TrimEnd(','), valueBuilder.ToString().TrimEnd(','));

            return GetQuery(sql).SetParameter(entity).Execute();
        }
        public override int Update(object entity, object id)
        {
            StringBuilder fieldValueBuilder = new StringBuilder();
            //解析
            var classMapping = ClassMappings.SingleOrDefault(m => entity.GetType().AssemblyQualifiedName.Replace(" ", "").StartsWith(m.Name));
            foreach (var p in classMapping.Propertys.Where(m => m.Update == true))
            {
                fieldValueBuilder.AppendFormat("{0}={1}{2},", Database.OpenQuote + p.Column + Database.CloseQuote, Database.ParameterToken, p.Name);
            }
            var sql = string.Format("update {0} set {1} where {2}", classMapping.Table, fieldValueBuilder.ToString().TrimEnd(','), MakeWhere(id));

            return GetQuery(sql).SetParameter(entity).SetParameter(id).Execute();
        } 
        public override int Delete<T>(object id)
        {
            //解析
            var classMapping = ClassMappings.SingleOrDefault(m => typeof(T).AssemblyQualifiedName.Replace(" ", "").StartsWith(m.Name));
            var sql = string.Format("delete from {0} where {1}", classMapping.Table, MakeWhere(id));

            return GetQuery(sql).SetParameter(id).Execute();
        }
        public override bool Exist<T>(object id)
        {
            //解析
            var classMapping = ClassMappings.SingleOrDefault(m => typeof(T).AssemblyQualifiedName.Replace(" ", "").StartsWith(m.Name));
            var sql = string.Format("select 1 from {0} where {1}", classMapping.Table, MakeWhere(id));

            var result = GetQuery(sql).SetParameter(id).UniqueResult();

            return result != null;
        }

        #endregion 

        /// <summary>
        /// 生成语句的where部分
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        string MakeWhere(object id)
        {
            StringBuilder whereBuilder = new StringBuilder();
            foreach (var p in id.GetType().GetProperties())
            {
                whereBuilder.AppendFormat(" and {0}={1}{2}", Database.OpenQuote + p.Name + Database.CloseQuote, Database.ParameterToken, p.Name);
            }
            if (whereBuilder.Length > 0)
                whereBuilder.Remove(0, 5);
            return whereBuilder.ToString();
        }
    }

    /// <summary>
    /// 数据库类型
    /// </summary>
    public enum DatabaseType
    { 
        MSSQL = 1,
        MySQL = 2,
        Sqlite = 3
    }
}